defmodule PlausibleWeb.Live.Components.VerificationTest do
  use PlausibleWeb.ConnCase, async: true

  on_ee do
    import Phoenix.LiveViewTest, only: [render_component: 2]

    alias Plausible.InstallationSupport.{State, Verification}

    @moduletag :capture_log

    @component PlausibleWeb.Live.Components.Verification
    @progress ~s|#verification-ui p#progress|

    @pulsating_circle ~s|div#verification-ui div.pulsating-circle|
    @check_circle ~s|div#verification-ui #check-circle|
    @error_circle ~s|div#verification-ui #error-circle|
    @recommendations ~s|#recommendation|
    @super_admin_report ~s|#super-admin-report|

    test "renders initial state" do
      html = render_component(@component, domain: "example.com")
      assert element_exists?(html, @progress)

      assert text_of_element(html, @progress) ==
               "We're visiting your site to ensure that everything is working"

      assert element_exists?(html, @pulsating_circle)
      refute class_of_element(html, @pulsating_circle) =~ "hidden"
      refute element_exists?(html, @recommendations)
      refute element_exists?(html, @check_circle)
      refute element_exists?(html, @super_admin_report)
    end

    test "renders error badge on error" do
      html = render_component(@component, domain: "example.com", success?: false, finished?: true)
      refute element_exists?(html, @pulsating_circle)
      refute element_exists?(html, @check_circle)
      refute element_exists?(html, @recommendations)
      assert element_exists?(html, @error_circle)
    end

    test "renders diagnostic interpretation" do
      interpretation =
        Verification.Checks.interpret_diagnostics(%State{
          url: "https://example.com",
          data_domain: "example.com",
          diagnostics: %Verification.Diagnostics{service_error: %{code: :domain_not_found}}
        })

      html =
        render_component(@component,
          domain: "example.com",
          success?: false,
          finished?: true,
          interpretation: interpretation
        )

      assert [recommendation] = html |> find(@recommendations) |> Enum.map(&text/1)
      assert recommendation =~ "check that the domain you entered is correct"

      refute element_exists?(html, @super_admin_report)
    end

    test "renders super-admin report" do
      state = %State{
        url: "https://example.com",
        data_domain: "example.com",
        diagnostics: %Verification.Diagnostics{}
      }

      interpretation = Verification.Checks.interpret_diagnostics(state)

      html =
        render_component(@component,
          domain: "example.com",
          success?: false,
          finished?: true,
          interpretation: interpretation,
          verification_state: state,
          super_admin?: true
        )

      assert element_exists?(html, @super_admin_report)
      assert text_of_element(html, @super_admin_report) =~ "Plausible is on window: nil"
    end

    test "hides pulsating circle when finished, shows check circle" do
      html =
        render_component(@component,
          domain: "example.com",
          success?: true,
          finished?: true
        )

      refute element_exists?(html, @pulsating_circle)
      assert element_exists?(html, @check_circle)
    end

    test "renders a progress message" do
      html = render_component(@component, domain: "example.com", message: "Arbitrary message")

      assert text_of_element(html, @progress) == "Arbitrary message"
    end

    test "renders contact link on >3 attempts" do
      html = render_component(@component, domain: "example.com", attempts: 2, finished?: true)
      refute html =~ "Need further help with your installation?"
      refute element_exists?(html, ~s|a[href="https://plausible.io/contact"]|)

      html = render_component(@component, domain: "example.com", attempts: 3, finished?: true)
      assert html =~ "Need further help with your installation?"
      assert element_exists?(html, ~s|a[href="https://plausible.io/contact"]|)
    end

    test "renders link to verify installation at a different URL" do
      interpretation =
        Verification.Checks.interpret_diagnostics(%State{
          url: "example.com",
          diagnostics: %Verification.Diagnostics{
            plausible_is_on_window: false,
            plausible_is_initialized: false,
            service_error: %{code: :domain_not_found}
          }
        })

      assert interpretation.data.offer_custom_url_input == true

      expected_link_href =
        PlausibleWeb.Router.Helpers.site_path(PlausibleWeb.Endpoint, :verification, "example.com")

      html =
        render_component(@component,
          domain: "example.com",
          finished?: true,
          success?: false,
          interpretation: interpretation
        )

      assert text_of_element(html, "#verify-custom-url-link") =~ "different URL?"
      assert text_of_attr(html, "#verify-custom-url-link a", "href") =~ expected_link_href
      assert text_of_attr(html, "#verify-custom-url-link a", "href") =~ "custom_url=true"
    end

    test "offers escape paths: settings and installation instructions on failure" do
      html =
        render_component(@component,
          domain: "example.com",
          success?: false,
          finished?: true,
          installation_type: "wordpress",
          flow: PlausibleWeb.Flows.review()
        )

      assert element_exists?(html, ~s|a[href="/example.com/settings/general"]|)

      assert element_exists?(
               html,
               ~s|a[href="/example.com/installation?flow=review&installation_type=wordpress"]|
             )
    end
  end
end
